package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PageUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.admin.service.MqMessageService;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.commons.utils.UserHolder;
import com.tanhua.domain.UserInfo;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VideoApi;
import com.tanhua.mongo.Video;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.vo.ErrorResult;
import com.tanhua.vo.PageResult;
import com.tanhua.vo.VideoVo;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class VideoService {
    @DubboReference
    private VideoApi videoApi;

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private FastFileStorageClient client;

    @Autowired
    private FdfsWebServer webServer;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @DubboReference
    private UserInfoApi userInfoApi;

    @Autowired
    private MqMessageService mqMessageService;

    /**
     * 发布小视频
     *
     * @param videoThumbnail
     * @param videoFile
     */
    @CacheEvict(value="videoList",allEntries = true)
    public void saveVideo(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        //判断封面图片文件和视频文件是否为空
        if (videoThumbnail == null || videoFile == null) {
            throw new BusinessException(ErrorResult.error());
        }
        //将视频上传至FastDFS，获取访问URL
        String filename = videoFile.getOriginalFilename();
        filename = filename.substring(filename.lastIndexOf(".") + 1);
        //第一个参数文件流，第二个参数文件size，第三个参数文件后缀，第四个参数文件元数据如作者信息，图片的长宽
        StorePath storePath = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(), filename, null);
        String fileUrl = webServer.getWebServerUrl() + storePath.getFullPath();
        //将封面保存到阿里云oss
        String thumbnailUrl = ossTemplate.saveMassage(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());
        //构建Videos对象
        Video video = new Video();
        video.setUserId(UserHolder.getUserId());
        video.setText("快来点赞吧");
        video.setPicUrl(thumbnailUrl);
        video.setVideoUrl(fileUrl);
        //调用API保存数据，根据返回videosID判断是否保存成功
        String videoId = videoApi.save(video);
        if (StringUtils.isEmpty(videoId)) {
            throw new BusinessException(ErrorResult.error());
        }
        //发送日志信息
        mqMessageService.sendLogService(UserHolder.getUserId(),"0301","video",videoId);
    }

    /**
     * 小视频列表
     *
     * @param page
     * @param pagesize
     * @return
     */
    @Cacheable(value = "videos" ,
            key = "T(com.tanhua.commons.utils.UserHolder).getUserId()+'_'+#page+'_'+#pagesize")
    public PageResult videos(Integer page, Integer pagesize) {
        //查询redis数据
        String redisKey = Constants.VIDEOS_RECOMMEND + UserHolder.getUserId();
        String redisValue = redisTemplate.opsForValue().get(redisKey);
        //判断redis数据是否存在，判断redis中数据是否满足分页条件
        List<Video> videoList = new ArrayList<>();
        int redisPages = 0;
        if (!StringUtils.isEmpty(redisValue)) {
            //如果redis数据存在，根据vid查询数据
            String[] split = redisValue.split(",");
            //如果起始页小于数据的总长度，则在redis推荐中取数据
            if ((page - 1) * pagesize <= split.length) {
                List<Long> ids = Arrays.stream(split).skip((page - 1) * pagesize)
                        .limit(pagesize)
                        .map(item -> Long.valueOf(item))
                        .collect(Collectors.toList());
                //根据ids查询video数据
                videoList = videoApi.findByIds(ids);
            }
            //初始化redisPages
            redisPages = PageUtil.totalPage(split.length,pagesize);
        }
        //如果redis数据不存在，分页查询视频数据
        if(videoList.isEmpty()){
            videoList = videoApi.queryVideoList(page - redisPages,pagesize);
        }
        //提取视频列表中所有用户id
        List<Long> ids = CollUtil.getFieldValues(videoList, "userId", Long.class);
        //查询用户信息
        Map<Long, UserInfo> map = userInfoApi.findByIds(ids, null);
        //构造返回对象
        ArrayList<VideoVo> list = new ArrayList<>();
        for (Video video : videoList) {
            UserInfo userInfo = map.get(video.getUserId());
            if(userInfo != null){
                VideoVo vo = VideoVo.init(userInfo, video);
                list.add(vo);
            }
        }
        return new PageResult(page,pagesize,0L,list);
    }
}
